#include "app_buffer.h"
#include <stdlib.h>
#include "log/log.h"
#include "stdio.h"
#include "string.h"

static SubBuffer_t *subBuffer_init(int size)
{
    SubBuffer_t *subBuffer = (SubBuffer_t *)malloc(sizeof(SubBuffer_t));
    subBuffer->ptr = (char *)malloc(size);
    subBuffer->size = size;
    subBuffer->len = 0;

    return subBuffer;
}

Buffer_t *app_buffer_init(int size)
{
    Buffer_t *buffer = (Buffer_t *)malloc(sizeof(Buffer_t));
    buffer->subBuffer[0] = subBuffer_init(size);
    buffer->subBuffer[1] = subBuffer_init(size);

    buffer->read_index = 0;
    buffer->write_index = 0;

    pthread_mutex_init(&buffer->read_lock, NULL);
    pthread_mutex_init(&buffer->write_lock, NULL);

    return buffer;
}

void app_buffer_free(Buffer_t *buffer)
{
    free(buffer->subBuffer[0]->ptr);
    free(buffer->subBuffer[1]->ptr);
    free(buffer->subBuffer[0]);
    free(buffer->subBuffer[1]);
    free(buffer);
}

int app_buffer_write(Buffer_t *buffer, char *data, int len)
{
    // 因为data[0]用来存储长度 因而限制不能超过255
    if (len > 255)
    {
        log_error("写入数据的长度不能超过255");
        return -1;
    }
    pthread_mutex_lock(&buffer->write_lock);

    // 获取写缓冲区
    SubBuffer_t *w_buffer = buffer->subBuffer[buffer->write_index];
    // 检查缓冲区空间是否充足
    // 这里加一是因为要额外存储数据的长度
    if (w_buffer->size - w_buffer->len < len + 1)
    {
        log_error("缓冲区空间不足");
        pthread_mutex_unlock(&buffer->write_lock);
        return -1;
    }
    // 先写入数据长度 再写数据
    // 在上一次写入数据长度之后
    w_buffer->ptr[w_buffer->len] = len;
    memcpy(w_buffer->ptr + w_buffer->len + 1, data, len);
    w_buffer->len += (len + 1);
    pthread_mutex_unlock(&buffer->write_lock);
    return 0;
}

// 切换缓冲区
void app_buffer_swap(Buffer_t *buffer)
{
    // 加写锁
    pthread_mutex_lock(&buffer->write_lock);
    int temp = buffer->write_index;
    buffer->write_index = buffer->read_index;
    buffer->read_index = temp;
    pthread_mutex_unlock(&buffer->write_lock);
}
int app_buffer_read(Buffer_t *buffer, char *data_buf, int buf_size)
{
    // 加读锁
    pthread_mutex_lock(&buffer->read_lock);
    SubBuffer_t *r_buffer = buffer->subBuffer[buffer->read_index];
    // 判断缓冲区是否为空 如果为空就要切换缓冲区
    if (r_buffer->len == 0)
    {
        app_buffer_swap(buffer);
        r_buffer = buffer->subBuffer[buffer->read_index];
        if (r_buffer->len == 0)
        {
            log_error("读取失败 缓冲区为空");
            pthread_mutex_unlock(&buffer->read_lock);
            return -1;
        }
    }

    // 读取当前帧数据的大小
    int len = r_buffer->ptr[0];
    if (len > buf_size)
    {
        log_error("读取失败 缓冲区数据长度超出");
        pthread_mutex_unlock(&buffer->read_lock);
        return -1;
    }
    // 读取当前帧数据
    memcpy(data_buf, r_buffer->ptr + 1, len);
    // 将缓冲区后面的数据前移
    memmove(r_buffer->ptr, r_buffer->ptr + len + 1, r_buffer->len - len - 1);

    // 更新缓冲区长度
    r_buffer->len -= (len + 1);
    pthread_mutex_unlock(&buffer->read_lock);
    // 返回读取的长度
    return len;
}
